package com.woniu.serviceorder.service;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.internalcommon.constant.CommonStatusEnum;
import com.woniu.internalcommon.constant.IdentityConstants;
import com.woniu.internalcommon.constant.OrderConstants;
import com.woniu.internalcommon.dto.ApiBossOrder;
import com.woniu.internalcommon.dto.Car;
import com.woniu.internalcommon.dto.OrderInfo;
import com.woniu.internalcommon.dto.ResponseResult;
import com.woniu.internalcommon.remote.ServiceDriverUserClient;
import com.woniu.internalcommon.remote.ServiceMapClient;
import com.woniu.internalcommon.remote.ServicePriceClient;
import com.woniu.internalcommon.remote.ServiceSsePushClient;
import com.woniu.internalcommon.request.DriverGrabRequest;
import com.woniu.internalcommon.request.OrderRequest;
import com.woniu.internalcommon.request.PriceRuleIsNewRequest;
import com.woniu.internalcommon.request.PushRequest;
import com.woniu.internalcommon.response.OrderDriverResponse;
import com.woniu.internalcommon.response.TerminalResponse;
import com.woniu.internalcommon.response.TraSearchResponse;
import com.woniu.serviceorder.entity.DriverOrderStatistics;
import com.woniu.serviceorder.mapper.DriverOrderStatisticsMapper;
import com.woniu.serviceorder.mapper.OrderInfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class OrderService {
    @Autowired
    ServiceDriverUserClient serviceDriverUserClient;

    @Autowired
    ServicePriceClient servicePriceClient;

    @Autowired
    OrderInfoMapper orderInfoMapper;

    @Autowired
    ServiceMapClient serviceMapClient;

    @Autowired
    @Qualifier("redissonBootYaml")
    RedissonClient redissonClient;

    @Autowired
    ServiceSsePushClient serviceSsePushClient;

    @Autowired
    DriverOrderStatisticsMapper driverOrderStatisticsMapper;
    public ResponseResult add(OrderRequest orderRequest) {
    //查找当前地区是否有可用的司机
        ResponseResult<Boolean> availableDriver = serviceDriverUserClient.isAlailableDriver(orderRequest.getAddress());
        //打印结果
        log.info("查找司机结果： "+availableDriver.getData());
        //如果没有返回错误格式CommonStatusEnum.CITY_DRIVER_EMPTY相关错误信息
        if(!availableDriver.getData()){
            return ResponseResult.fail(CommonStatusEnum.CITY_DRIVER_EMPTY.getCode(),CommonStatusEnum.CITY_DRIVER_EMPTY.getValue());

        }

        //判断计价规则是否最新
        PriceRuleIsNewRequest priceRuleIsNewRequest=new PriceRuleIsNewRequest();
        //获取下单请求中的计价规则类型和版本
        priceRuleIsNewRequest.setFareType(orderRequest.getFareType());
        priceRuleIsNewRequest.setFareVersion(orderRequest.getFareVersion());
        ResponseResult<Boolean> aNew= servicePriceClient.isNew(priceRuleIsNewRequest);
        //返回CommonStatusEnum.PRICE_RULE_CHANGED的错误信息
        if (!aNew.getData()){
            return ResponseResult.fail(CommonStatusEnum.PRICE_RULE_CHANGED.getCode(),CommonStatusEnum.PRICE_RULE_CHANGED.getValue());
        }
        //忽略判断是否是黑名单设别，因为这里没有添加黑名单的选项

        //计价规则最新后，检查下单的城市的计价规则是否正常
        if(!isPriceRuleExists(orderRequest)){
            return ResponseResult.fail(CommonStatusEnum.CITY_SERVICE_NOT_SERVICE.getCode(),CommonStatusEnum.CITY_SERVICE_NOT_SERVICE.getValue());
        }

        //判断乘客是否有进行中的订单
        if (isPassengerOrderGoingon(orderRequest.getPassengerId())>0){
            return ResponseResult.fail(CommonStatusEnum.ORDER_GOING_ON.getCode(),CommonStatusEnum.ORDER_GOING_ON.getValue());
        }

        //创建订单
        OrderInfo orderInfo=new OrderInfo();

        BeanUtils.copyProperties(orderRequest,orderInfo);
        //设置订单初始状态
        orderInfo.setOrderStatus(OrderConstants.ORDER_START);
        LocalDateTime now=LocalDateTime.now();
        orderInfo.setGmtCreate(now);
        orderInfo.setGmtModified(now);

        orderInfoMapper.insert(orderInfo);

        //定时任务处理派单
        for (int i=0;i<6;i++){
            //实时派单方法
            int result = dispatchRealTimeOrder(orderInfo);
            if(result==1){
                break;
            }
            if (i==5){
                //订单无效
                orderInfo.setOrderStatus(OrderConstants.ORDER_INVALID);
                orderInfoMapper.updateById(orderInfo);
            }else {
                //等待5s
                try {
                    Thread.sleep(5000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        }

        return ResponseResult.success();
    }

    /**
     * 预定订单
     * @param orderRequest
     * @return
     */

    public ResponseResult book(OrderRequest orderRequest) {

        // 创建订单
        OrderInfo orderInfo = new OrderInfo();

        BeanUtils.copyProperties(orderRequest,orderInfo);

        orderInfo.setOrderStatus(OrderConstants.ORDER_START);

        LocalDateTime now = LocalDateTime.now();
        orderInfo.setGmtCreate(now);
        orderInfo.setGmtModified(now);

        orderInfoMapper.insert(orderInfo);

        // 定时任务的处理
        for (int i =0;i<6;i++){
            // 预定派单 dispatchBookOrder
            int result = dispatchBookOrder(orderInfo);
            if (result == 1){
                break;
            }
            //这里没有循环修改订单的状态
            // 等待5s
            try {
                Thread.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        return ResponseResult.success();
    }

    /**
     * 预约订单-分发订单
     * @param orderInfo
     * @return
     */
    private int dispatchBookOrder(OrderInfo orderInfo) {
        log.info("单词循环book");
        int result =0;
        //获取订单的
        String depLatitude = orderInfo.getDepLatitude();
        String depLongitude = orderInfo.getDepLongitude();

        String center = depLatitude+","+depLongitude;

        List<Integer> radiusList = new ArrayList<>();
        radiusList.add(2000);
        radiusList.add(4000);
        radiusList.add(5000);

        ResponseResult<List<TerminalResponse>> listResponseResult=null;
        radius:
        for (int i=0;i<radiusList.size();i++){
            Integer radius= radiusList.get(i);
            listResponseResult =serviceMapClient.terminalAroundSearch(center,radius);
            log.info("在半径为"+radius+"的范围内，寻找车辆,结果："+ JSONUtil.parseArray(listResponseResult.getData()).toString());
            //解析终端
            List<TerminalResponse> data=listResponseResult.getData();

            for (int j=0;j<data.size();j++){
                TerminalResponse terminalResponse=data.get(j);
                Long carId = terminalResponse.getCarId();
                String latitude = terminalResponse.getLatitude();
                String longitude = terminalResponse.getLongitude();

                //查询是否有对应的可派单司机
                ResponseResult<OrderDriverResponse> availableDriver =serviceDriverUserClient.getAvailableDriver(carId);
                if (availableDriver.getCode()==CommonStatusEnum.AVAILABLE_DRIVER_EMPTY.getCode()){
                    log.info("没有车辆ID："+carId+",对于的司机");
                    continue;
                }else {
                    log.info("车辆ID："+carId+"找到了正在出车的司机");
                    //获取司机信息
                    OrderDriverResponse orderDriverResponse=availableDriver.getData();
                    Long driverId = orderDriverResponse.getDriverId();
                    String driverPhone = orderDriverResponse.getDriverPhone();
                    String licenseId = orderDriverResponse.getLicenseId();
                    String vehicleNo = orderDriverResponse.getVehicleNo();
                    String vehicleType = orderDriverResponse.getVehicleType();

                    //判断车辆的车型是否符合订单车型
                    String orderInfoVehicleType = orderInfo.getVehicleType();
                    if (!orderInfoVehicleType.equals(vehicleType)){
                        log.info("车型不符合");
                        continue ;
                    }
                    //通知司机
                    JSONObject driverContent = new  JSONObject();

                    driverContent.put("orderId",orderInfo.getId());
                    driverContent.put("passengerId",orderInfo.getPassengerId());
                    driverContent.put("passengerPhone",orderInfo.getPassengerPhone());
                    driverContent.put("departure",orderInfo.getDeparture());
                    driverContent.put("depLongitude",orderInfo.getDepLongitude());
                    driverContent.put("depLatitude",orderInfo.getDepLatitude());

                    driverContent.put("destination",orderInfo.getDestination());
                    driverContent.put("destLongitude",orderInfo.getDestLongitude());
                    driverContent.put("destLatitude",orderInfo.getDestLatitude());

                    PushRequest pushRequest = new PushRequest();
                    pushRequest.setUserId(driverId);
                    pushRequest.setIdentity(IdentityConstants.DRIVER_IDENTITY);
                    pushRequest.setContent(driverContent.toString());

                    serviceSsePushClient.push(pushRequest);
                    result = 1;

                    // 退出，不在进行 司机的查找.如果派单成功，则退出循环
                    break radius;

                }
            }
        }
        return result;
    }

    /**
     * 实时派单逻辑
     * @param orderInfo
     * @return
     */
    private int dispatchRealTimeOrder(OrderInfo orderInfo) {
        log.info("单词循环");
        int result=0;
        //拿到经纬度
        String depLatitude = orderInfo.getDepLatitude();
        String depLongitude = orderInfo.getDepLongitude();
        String center = depLatitude+","+depLongitude;
        //设置搜索半径队列
        List<Integer> radiusList = new ArrayList<>();
        radiusList.add(2000);
        radiusList.add(4000);
        radiusList.add(5000);
        //
        ResponseResult<List<TerminalResponse>> listResponseResult=null;

        //使用redius：是为了方便跳出循环
        //每次循环，切换搜索半径
        radius:
        for (int i = 0; i < radiusList.size(); i++) {
            Integer radius= radiusList.get(i);
            listResponseResult =serviceMapClient.terminalAroundSearch(center,radius);
            log.info("在半径为"+radius+"的范围内，寻找车辆,结果："+ JSONUtil.parseArray(listResponseResult.getData()).toString());

            //解析终端,拿到数据
            List<TerminalResponse> data=listResponseResult.getData();

            //测试从地图上拿到获取到司机
            for (int j=0;j<data.size();j++){
                TerminalResponse terminalResponse =data.get(j);
                Long carId =terminalResponse.getCarId();

                String longitude = terminalResponse.getLongitude();
                String latitude = terminalResponse.getLatitude();
                // 查询是否有对应的可派单司机
                ResponseResult<OrderDriverResponse> availableDriver =serviceDriverUserClient.getAvailableDriver(carId);
                if (availableDriver.getCode()==CommonStatusEnum.AVAILABLE_DRIVER_EMPTY.getCode()){
                    log.info("没有车辆ID："+carId+",对于的司机");
                    continue ;
                }else {
                    //拿到可以派单司机的数据
                    log.info("车辆ID："+carId+"找到了正在出车的司机");
                    OrderDriverResponse orderDriverResponse =availableDriver.getData();
                    Long driverId= orderDriverResponse.getDriverId();
                    String driverPhone=orderDriverResponse.getDriverPhone();
                    String licenseId = orderDriverResponse.getLicenseId();
                    String vehicleNo = orderDriverResponse.getVehicleNo();
                    String vehicleType = orderDriverResponse.getVehicleType();

                    //判断车辆的车型是否符合下单车型
                    String orderInfoVehicleType = orderInfo.getVehicleType();
                    if (!vehicleType.trim().equals(orderInfoVehicleType)){
                        log.info("车型不符合");
                        continue ;
                    }
                    //使用redisson
                    String lockKey=(driverId+"").intern();
                    RLock lock=redissonClient.getLock(lockKey);
                    lock.lock();

                    //判断司机 是否有进行中的订单
                    if(isDriverOrderGoingon(driverId)>0){
                        //司机有未完成的订单，解锁
                        lock.unlock();
                        continue ;
                    }
                    //订单完成匹配司机
                    //查询当前车辆的信息
//                    QueryWrapper queryWrapper=new QueryWrapper();
//                    queryWrapper.eq("in",carId);
                    orderInfo.setReceiveOrderTime(LocalDateTime.now());
                    orderInfo.setReceiveOrderCarLatitude(latitude);
                    orderInfo.setReceiveOrderCarLongitude(longitude);
                    orderInfo.setVehicleNo(vehicleNo);
                    orderInfo.setOrderStatus(OrderConstants.DRIVER_RECEIVE_ORDER);

                    orderInfoMapper.updateById(orderInfo);

                    //通知司机
                    JSONObject driverContent = new JSONObject();
                    driverContent.put("orderId",orderInfo.getId());
                    driverContent.put("passengerId",orderInfo.getPassengerId());
                    driverContent.put("passengerPhone",orderInfo.getPassengerPhone());
                    driverContent.put("departure",orderInfo.getDeparture());
                    driverContent.put("depLongitude",orderInfo.getDepLongitude());
                    driverContent.put("depLatitude",orderInfo.getDepLatitude());

                    driverContent.put("destination",orderInfo.getDestination());
                    driverContent.put("destLongitude",orderInfo.getDestLongitude());
                    driverContent.put("destLatitude",orderInfo.getDestLatitude());

                    send(driverId, IdentityConstants.DRIVER_IDENTITY,driverContent.toString());



                    //通知乘客
                    // 通知乘客
                    JSONObject passengerContent = new  JSONObject();
                    passengerContent.put("orderId",orderInfo.getId());
                    passengerContent.put("driverId",orderInfo.getDriverId());
                    passengerContent.put("driverPhone",orderInfo.getDriverPhone());
                    passengerContent.put("vehicleNo",orderInfo.getVehicleNo());

                    //车辆信息，调用车辆服务

                    ResponseResult<Car> carById=serviceDriverUserClient.getCarById(carId);

                    Car carRemote= carById.getData();

                    passengerContent.put("brand", carRemote.getBrand());
                    passengerContent.put("model",carRemote.getModel());
                    passengerContent.put("vehicleColor",carRemote.getVehicleColor());

                    passengerContent.put("receiveOrderCarLongitude",orderInfo.getReceiveOrderCarLongitude());
                    passengerContent.put("receiveOrderCarLatitude",orderInfo.getReceiveOrderCarLatitude());

                    send(orderInfo.getPassengerId(), IdentityConstants.PASSENGER_IDENTITY, passengerContent.toString());

                    result = 1;
                    lock.unlock();

                    //退出 ,如果找到司机会跳出双重循环
                    break  radius;
                }

            }
        }
        return result;
    }

    public void  send(Long id ,String idemtity,String message){
        PushRequest pushRequest =new PushRequest();
        pushRequest.setUserId(id);
        pushRequest.setIdentity(idemtity);
        pushRequest.setContent(message);

        serviceSsePushClient.push(pushRequest);
    }

    /**
     * 判断司机正在进行当中的订单数量
     *
     * @param driverId
     * @return
     */
    private Long isDriverOrderGoingon(Long driverId) {
        //从数据库中拿去正在进行中的订单
        QueryWrapper<OrderInfo> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("driver_id",driverId);
        //如果有以下业务的司机不允许接单
        queryWrapper.and(wrapper->wrapper
                .eq("order_status",OrderConstants.DRIVER_RECEIVE_ORDER)
                .or().eq("order_status",OrderConstants.DRIVER_TO_PICK_UP_PASSENGER)
                .or().eq("order_status",OrderConstants.DRIVER_ARRIVED_DEPARTURE)
                .or().eq("order_status",OrderConstants.PICK_UP_PASSENGER)
        );

        Long count = orderInfoMapper.selectCount(queryWrapper);
        log.info("司机id"+driverId+"，正在进行当中的订单数量： "+count);
        return  count;
    }

    private long isPassengerOrderGoingon(Long passengerId) {
    //判断乘客是否有没有结束业务的订单
        //使用mybatisplus
        QueryWrapper<OrderInfo> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("passenger_id",passengerId);
        queryWrapper.and(wrapper->wrapper.eq("order_status", OrderConstants.ORDER_START))
                .or().eq("order_status",OrderConstants.DRIVER_RECEIVE_ORDER)
                .or().eq("order_status",OrderConstants.DRIVER_TO_PICK_UP_PASSENGER)
                .or().eq("order_status",OrderConstants.DRIVER_ARRIVED_DEPARTURE)
                .or().eq("order_status",OrderConstants.PICK_UP_PASSENGER)
                .or().eq("order_status",OrderConstants.PASSENGER_GETOFF)
                .or().eq("order_status",OrderConstants.TO_START_PAY);
        long validOrderNumber= orderInfoMapper.selectCount(queryWrapper);
        return validOrderNumber;
    }


    /**
     * 判断计价规则是否存在
     * @param orderRequest
     * @return boolean
     */
    private boolean isPriceRuleExists(OrderRequest orderRequest) {
       String fareType=orderRequest.getFareType();
       int index=fareType.indexOf("$");
       //获取城市编码和车辆类型
       String cityCode=fareType.substring(0,index);
       String vehicleType=fareType.substring(index,-1);

        ResponseResult<Boolean> booleanResponseResult=servicePriceClient.ifPriceExists(cityCode,vehicleType);

        return booleanResponseResult.getData();
    }

    /**
     * 去接乘客
     * @param orderRequest
     * @return
     */
    public ResponseResult toPickPassenger(OrderRequest orderRequest){
        Long orderId=orderRequest.getOrderId();
        //获取去接乘客的信息
        LocalDateTime toPickPassengerTime=orderRequest.getToPickUpPassengerTime();
        String toPickUpPassengerLongitude = orderRequest.getToPickUpPassengerLongitude();
        String toPickUpPassengerLatitude = orderRequest.getToPickUpPassengerLatitude();
        String toPickUpPassengerAddress = orderRequest.getToPickUpPassengerAddress();
        //读取数据库信息
        QueryWrapper queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("id",orderId);
        OrderInfo orderInfo=orderInfoMapper.selectOne(queryWrapper);

        //更新数据库信息
        orderInfo.setToPickUpPassengerAddress(toPickUpPassengerAddress);
        orderInfo.setToPickUpPassengerLatitude(toPickUpPassengerLatitude);
        orderInfo.setToPickUpPassengerLongitude(toPickUpPassengerLongitude);
        orderInfo.setToPickUpPassengerTime(LocalDateTime.now());
        orderInfo.setOrderStatus(OrderConstants.DRIVER_TO_PICK_UP_PASSENGER);

        orderInfoMapper.updateById(orderInfo);

        return ResponseResult.success();
    }

    /**
     * 司机到达乘客上车点
     * @param orderRequest
     * @return
     */
    public ResponseResult arrivedDeparture(OrderRequest orderRequest){
        Long orderId = orderRequest.getOrderId();

        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",orderId);

        OrderInfo orderInfo = orderInfoMapper.selectOne(queryWrapper);
        orderInfo.setOrderStatus(OrderConstants.DRIVER_ARRIVED_DEPARTURE);

        orderInfo.setDriverArrivedDepartureTime(LocalDateTime.now());
        orderInfoMapper.updateById(orderInfo);
        return ResponseResult.success();
    }


    /**
     * 司机接到乘客
     * @param orderRequest
     * @return
     */
    public ResponseResult pickUpPassenger( OrderRequest orderRequest){
        Long orderId = orderRequest.getOrderId();

        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",orderId);
        OrderInfo orderInfo = orderInfoMapper.selectOne(queryWrapper);

        orderInfo.setPickUpPassengerLongitude(orderRequest.getPickUpPassengerLongitude());
        orderInfo.setPickUpPassengerLatitude(orderRequest.getPickUpPassengerLatitude());
        orderInfo.setPickUpPassengerTime(LocalDateTime.now());
        orderInfo.setOrderStatus(OrderConstants.PICK_UP_PASSENGER);

        orderInfoMapper.updateById(orderInfo);
        return ResponseResult.success();
    }

    /**
     * 送达目的地
     * @param orderRequest
     * @return
     */

    public ResponseResult passengerGetoff(OrderRequest orderRequest){
        Long orderId = orderRequest.getOrderId();

        //查询数据库订单信息
        QueryWrapper queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("id",orderId);
        OrderInfo orderInfo=orderInfoMapper.selectOne(queryWrapper);

        //设置订单
        orderInfo.setPassengerGetoffTime(LocalDateTime.now());
        orderInfo.setPassengerGetoffLongitude(orderRequest.getPassengerGetoffLongitude());
        orderInfo.setPassengerGetoffLatitude(orderRequest.getPassengerGetoffLatitude());

        orderInfo.setOrderStatus(OrderConstants.PASSENGER_GETOFF);

        //调用订单行驶的路程和时间，调用service-map
        ResponseResult<Car> carResponseResult=serviceDriverUserClient.getCarById(orderInfo.getCarId());
        long startTime = orderInfo.getPickUpPassengerTime().toInstant(ZoneOffset.of("+8")).toEpochMilli();
        long endTime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
        log.info("开始时间"+startTime);
        log.info("结束时间"+endTime);

        ResponseResult<TraSearchResponse> trsearch=serviceMapClient.traSearch(carResponseResult.getData().getTid(),startTime,endTime);
        TraSearchResponse data = trsearch.getData();
        Long driveMile = data.getDriveMile();
        Long driveTime = data.getDriveTime();

        orderInfo.setDriveMile(driveMile);
        orderInfo.setDriveTime(driveTime);

        //获取价格
        String address=orderInfo.getAddress();
        String vehicleType = orderInfo.getVehicleType();
        ResponseResult<Double> doubleResponseResult = servicePriceClient.calculatePrice(driveMile.intValue(), driveTime.intValue(), address, vehicleType);
        double price=doubleResponseResult.getData();
        orderInfo.setPrice(price);

        orderInfoMapper.updateById(orderInfo);

        return  ResponseResult.success();

    }
    /**
     * 支付
     * @param orderRequest
     * @return
     */
    public ResponseResult pay(OrderRequest orderRequest){

        Long orderId = orderRequest.getOrderId();
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);

        orderInfo.setOrderStatus(OrderConstants.SUCCESS_PAY);
        orderInfoMapper.updateById(orderInfo);
        return ResponseResult.success();
    }

    /**
     * 取消订单
     * @param orderId
     * @param identity
     * @return
     */
    public ResponseResult cancel(Long orderId,String identity){
        //查询订单当前状态
        OrderInfo orderInfo=orderInfoMapper.selectById(orderId);
        Integer orderStatus = orderInfo.getOrderStatus();

        LocalDateTime cancelTime = LocalDateTime.now();
        Integer cancelOperator=null;
        Integer cancelTypeCode=null;

        //正常取消
        int cancelType=1;

        //更新订单取消的状态
        //乘客取消
        if (identity.trim().equals(IdentityConstants.PASSENGER_IDENTITY)){
            switch (orderStatus){
                //根据订单执行情况决定是否取消订单
                case OrderConstants.ORDER_START:
                    cancelTypeCode = OrderConstants.CANCEL_PASSENGER_BEFORE;
                    break;
                // 司机接到订单
                case OrderConstants.DRIVER_RECEIVE_ORDER:
                    LocalDateTime receiveOrderTime = orderInfo.getReceiveOrderTime();
                    long between = ChronoUnit.MINUTES.between(receiveOrderTime, cancelTime);
                    if (between > 1){
                        cancelTypeCode = OrderConstants.CANCEL_PASSENGER_ILLEGAL;
                    }else {
                        cancelTypeCode = OrderConstants.CANCEL_PASSENGER_BEFORE;
                    }
                    break;
                // 司机去接乘客
                case OrderConstants.DRIVER_TO_PICK_UP_PASSENGER:
                    // 司机到达乘客起点
                case OrderConstants.DRIVER_ARRIVED_DEPARTURE:
                    cancelTypeCode = OrderConstants.CANCEL_PASSENGER_ILLEGAL;
                    break;
                default:
                    log.info("乘客取消失败");
                    cancelType = 0;
                    break;
                }
            }
        // 如果是司机取消
        if (identity.trim().equals(IdentityConstants.DRIVER_IDENTITY)){
            switch (orderStatus){
                // 订单开始
                // 司机接到乘客
                case OrderConstants.DRIVER_RECEIVE_ORDER:
                case OrderConstants.DRIVER_TO_PICK_UP_PASSENGER:
                case OrderConstants.DRIVER_ARRIVED_DEPARTURE:
                    LocalDateTime receiveOrderTime = orderInfo.getReceiveOrderTime();
                    long between = ChronoUnit.MINUTES.between(receiveOrderTime, cancelTime);
                    if (between > 1){
                        cancelTypeCode = OrderConstants.CANCEL_DRIVER_ILLEGAL;
                    }else {
                        cancelTypeCode = OrderConstants.CANCEL_DRIVER_BEFORE;
                    }
                    break;

                default:
                    log.info("司机取消失败");
                    cancelType = 0;
                    break;
                }
            }

        if (cancelType == 0){
            return ResponseResult.fail(CommonStatusEnum.ORDER_CANCEL_ERROR.getCode(),CommonStatusEnum.ORDER_CANCEL_ERROR.getValue());
        }

        orderInfo.setCancelTypeCode(cancelTypeCode);
        orderInfo.setCancelTime(cancelTime);
        orderInfo.setCancelOperator(Integer.parseInt(identity));
        orderInfo.setOrderStatus(OrderConstants.ORDER_CANCEL);

        orderInfoMapper.updateById(orderInfo);

        return ResponseResult.success();
    }

    /**
     * 司机发起收款
     * @param orderRequest
     * @return
     */
    public ResponseResult pushPayInfo(OrderRequest orderRequest) {

        Long orderId = orderRequest.getOrderId();

        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        orderInfo.setOrderStatus(OrderConstants.TO_START_PAY);
        orderInfoMapper.updateById(orderInfo);
        return ResponseResult.success();

    }

    /**
     * 查看订单详情
     * @param id
     * @return
     */
    public ResponseResult<OrderInfo> detail(Long id){
        OrderInfo orderInfo =  orderInfoMapper.selectById(id);
        return ResponseResult.success(orderInfo);
    }

    /**
     * 通过手机号查询未完成的订单
     * @param phone
     * @param identity
     * @return
     */
    public ResponseResult<OrderInfo> current(String phone, String identity){
        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();

        if (identity.equals(IdentityConstants.DRIVER_IDENTITY)){
            queryWrapper.eq("driver_phone",phone);

            queryWrapper.and(wrapper->wrapper
                    .eq("order_status",OrderConstants.DRIVER_RECEIVE_ORDER)
                    .or().eq("order_status",OrderConstants.DRIVER_TO_PICK_UP_PASSENGER)
                    .or().eq("order_status",OrderConstants.DRIVER_ARRIVED_DEPARTURE)
                    .or().eq("order_status",OrderConstants.PICK_UP_PASSENGER)

            );
        }
        if (identity.equals(IdentityConstants.PASSENGER_IDENTITY)){
            queryWrapper.eq("passengerPhone",phone);
            queryWrapper.and(wrapper->wrapper.eq("order_status",OrderConstants.ORDER_START)
                    .or().eq("order_status",OrderConstants.DRIVER_RECEIVE_ORDER)
                    .or().eq("order_status",OrderConstants.DRIVER_TO_PICK_UP_PASSENGER)
                    .or().eq("order_status",OrderConstants.DRIVER_ARRIVED_DEPARTURE)
                    .or().eq("order_status",OrderConstants.PICK_UP_PASSENGER)
                    .or().eq("order_status",OrderConstants.PASSENGER_GETOFF)
                    .or().eq("order_status",OrderConstants.TO_START_PAY)
            );
        }

        OrderInfo orderInfo = orderInfoMapper.selectOne(queryWrapper);
        return ResponseResult.success(orderInfo);
    }

    /**
     * 司机抢单-本地事务管理
     * @param driverGrabRequest
     * @return
     */
    @Transactional
    public ResponseResult grab(DriverGrabRequest driverGrabRequest){
        Long orderId = driverGrabRequest.getOrderId();
        String orderIdStr = (orderId + "").intern();

        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);

        if (orderInfo==null){
            return  ResponseResult.fail(CommonStatusEnum.ORDER_NOT_EXISTS.getCode(),CommonStatusEnum.ORDER_NOT_EXISTS.getValue());
        }
        Integer orderStatus = orderInfo.getOrderStatus();

        if (orderStatus!=OrderConstants.ORDER_START){
            return  ResponseResult.fail(CommonStatusEnum.ORDER_CAN_NOT_GRAB.getCode(),CommonStatusEnum.ORDER_CAN_NOT_GRAB.getValue());
        }
        try {
            TimeUnit.SECONDS.sleep(2);
        }catch (InterruptedException e){
            e.printStackTrace();
        }

        //获取司机信息
        Long driverId = driverGrabRequest.getDriverId();
        Long carId = driverGrabRequest.getCarId();
        String licenseId = driverGrabRequest.getLicenseId();
        String vehicleNo = driverGrabRequest.getVehicleNo();
        String receiveOrderCarLatitude = driverGrabRequest.getReceiveOrderCarLatitude();
        String receiveOrderCarLongitude = driverGrabRequest.getReceiveOrderCarLongitude();
        String vehicleType = driverGrabRequest.getVehicleType();
        String driverPhone = driverGrabRequest.getDriverPhone();

        //更新orderinfo，并更新数据库
        orderInfo.setDriverId(driverId);
        orderInfo.setDriverPhone(driverPhone);
        orderInfo.setCarId(carId);

        orderInfo.setReceiveOrderCarLongitude(receiveOrderCarLongitude);
        orderInfo.setReceiveOrderCarLatitude(receiveOrderCarLatitude);
        orderInfo.setReceiveOrderTime(LocalDateTime.now());

        orderInfo.setLicenseId(licenseId);
        orderInfo.setVehicleNo(vehicleNo);

        orderInfo.setVehicleType(vehicleType);

        orderInfo.setOrderStatus(OrderConstants.DRIVER_RECEIVE_ORDER);

        orderInfoMapper.updateById(orderInfo);

        //添加司机当天抢单成功的数量
        //查询当天数据
        QueryWrapper queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("grab_order_date",LocalDateTime.now());
        queryWrapper.eq("driver_id",driverId);
        DriverOrderStatistics driverOrderStatistics = driverOrderStatisticsMapper.selectOne(queryWrapper);

        if (driverOrderStatistics==null){
            //如果当天司机没有抢单，则新增抢单数据，插入到数据库
            driverOrderStatistics = new DriverOrderStatistics();
            driverOrderStatistics.setGrabOrderDate(LocalDate.now());
            driverOrderStatistics.setGrabOrderSuccessCount(1);
            driverOrderStatistics.setDriverId(driverId);
            driverOrderStatisticsMapper.insert(driverOrderStatistics);
        }else {
            //反之，数据加一
            driverOrderStatistics.setGrabOrderSuccessCount(driverOrderStatistics.getGrabOrderSuccessCount()+1);
            driverOrderStatisticsMapper.updateById(driverOrderStatistics);
        }
        //推送逻辑
        //通知乘客
        JSONObject passengerContent = new JSONObject();
        passengerContent.put("orderId",orderInfo.getId());
        passengerContent.put("driverId",orderInfo.getDriverId());
        passengerContent.put("driverPhone",orderInfo.getDriverPhone());
        passengerContent.put("vehicleNo",orderInfo.getVehicleNo());
        //加入车辆信息
        ResponseResult<Car> carById = serviceDriverUserClient.getCarById(carId);
        Car carRemote = carById.getData();

        passengerContent.put("brand", carRemote.getBrand());
        passengerContent.put("model",carRemote.getModel());
        passengerContent.put("vehicleColor",carRemote.getVehicleColor());

        passengerContent.put("receiveOrderCarLongitude",orderInfo.getReceiveOrderCarLongitude());
        passengerContent.put("receiveOrderCarLatitude",orderInfo.getReceiveOrderCarLatitude());

        send(orderInfo.getPassengerId(), IdentityConstants.PASSENGER_IDENTITY, passengerContent.toString());



        return  ResponseResult.success();

    }

    public ResponseResult<Page<OrderInfo>> select(@RequestBody ApiBossOrder apiBossOrder){
        log.info("分页查参数，{}",apiBossOrder);
        Page<OrderInfo> objectPage = new Page<>();
        objectPage.setCurrent(apiBossOrder.getPageNum());
        objectPage.setSize(apiBossOrder.getPageSize());
        OrderInfo orderInfo = apiBossOrder.getOrderInfo();
        Long orderId = orderInfo.getId();
        Long passengerId = orderInfo.getPassengerId();
        String passengerPhone = orderInfo.getPassengerPhone();
        Long driverId = orderInfo.getDriverId();
        String driverPhone = orderInfo.getDriverPhone();
        QueryWrapper<OrderInfo> queryWrapper=new QueryWrapper<>();
        if (orderId!=0){
            queryWrapper.eq("id",orderId);
        }
        if (passengerId!=0){
            queryWrapper.eq("passenger_id",passengerId);
        }
        if (passengerPhone!=null&passengerPhone!=""){
            queryWrapper.eq("passengerPhone",passengerPhone);
        }
        if (driverId!=0){
            queryWrapper.eq("driver_id",driverId);
        }
        if (driverPhone!=null & driverPhone!=""){
            queryWrapper.eq("driver_phone",driverPhone);
        }
        Page<OrderInfo> orderInfoPage = orderInfoMapper.selectPage(objectPage, queryWrapper);
        return ResponseResult.success(orderInfoPage);
    }
}



